#ifdef _MSC_VER
#pragma warning( disable : 4244 )
#endif

#include "sgl_types.h"
#include "sdy_events.h"
#include "sgl.h"
#include "target_configuration.h"
#include "aol_imported_functions.h"

/* Pointer storage */
static sdy_pointer_event_t pointer_events[MAX_POINTERS] = {0};
static int last_pointer_event = 0;

/* Keyboard storage */
static sdy_keyboard_event_t keyboard_events[MAX_KEYBOARDS] = {0};
static int last_keyboard_event = 0;



/* Cursor position request callback */
static T_CURSOR_POS_REQUEST_CALLBACK cursor_pos_request_cb = 0;
static void *cursor_pos_request_data = 0;

/* AsynchronousACK sensor for Widget Library */
SGLbool BHVR_AsynchronousACK = SGL_FALSE;

/* Imported functions for SCADE Display KCG Code */

void aol_locate(SGLlong pPointer, SGLfloat* pX, SGLfloat* pY) {
  int index;
  for (index=0; index<last_pointer_event; index++) {
    const sdy_pointer_event_t *lPointerEvent = &pointer_events[index];
    if ((pPointer == -1) || (lPointerEvent->id == -1) || (pPointer == lPointerEvent->id)) {
      if (pX != SGL_NULL) *pX = lPointerEvent->position[0];
      if (pY != SGL_NULL) *pY = lPointerEvent->position[1];
      break;
    }
  }
}

void aol_pointer(SGLlong pPointer, SGLbool* pPressed, SGLbool* pReleased, SGLlong* pButton, SGLfloat* pX, SGLfloat* pY, SGLlong* pModifiers) {
  int index;
  for (index=0; index<last_pointer_event; index++) {
    const sdy_pointer_event_t *lPointerEvent = &pointer_events[index];
    if ((pPointer == -1) || (lPointerEvent->id == -1) || (pPointer == lPointerEvent->id)) {
      if (pPressed != SGL_NULL) *pPressed = lPointerEvent->pressed;
      if (pReleased != SGL_NULL) *pReleased = lPointerEvent->released;
      if (pButton != SGL_NULL) *pButton = lPointerEvent->button;
      if (pX != SGL_NULL) *pX =  lPointerEvent->position[0];
      if (pY != SGL_NULL) *pY =  lPointerEvent->position[1];
      if (pModifiers != SGL_NULL) *pModifiers =  lPointerEvent->modifiers;
      break;
    }
  }
}

void aol_keyboard(SGLlong pKeyboard, SGLbool* pPressed, SGLbool* pReleased, SGLlong* pCode, SGLlong* pModifiers) {
  int index;
  for (index=0; index<last_keyboard_event; index++) {
    const sdy_keyboard_event_t *lKeyboardEvent = &keyboard_events[index];
    if ((pKeyboard == -1) || (lKeyboardEvent->id == -1) || (pKeyboard == lKeyboardEvent->id)) {
      if (pPressed != SGL_NULL) *pPressed = lKeyboardEvent->pressed;
      if (pReleased != SGL_NULL) *pReleased = lKeyboardEvent->released;
      if (pCode != SGL_NULL) *pCode = lKeyboardEvent->keycode;
      if (pModifiers != SGL_NULL) *pModifiers = lKeyboardEvent->modifiers;
      break;
    }
  }
}

void aol_cursor(SGLlong pCursor, SGLfloat pX, SGLfloat pY) {
  if (cursor_pos_request_cb != 0) {
    cursor_pos_request_cb(cursor_pos_request_data, pCursor, pX, pY);
  }
}

/* Setter functions for pointer and keyboard */
void BHVR_SetPointer(SGLint32 id, SGLfloat x, SGLfloat y,  SGLint32 button, SGLbool pressed, SGLbool released, SGLint32 modifiers){
int index;
  for (index=0; index<MAX_POINTERS; index++) {
    if (index >= last_pointer_event) {
      last_pointer_event++;
      pointer_events[index].id = id;
      pointer_events[index].position[0] = x;
      pointer_events[index].position[1] = y;
      pointer_events[index].button = button;
      pointer_events[index].pressed = pressed;
      pointer_events[index].released = released;
      pointer_events[index].modifiers = modifiers;
      break;
    }
    else if (pointer_events[index].id == id) {
      pointer_events[index].id = id;
      pointer_events[index].position[0] = x;
      pointer_events[index].position[1] = y;
      pointer_events[index].button = button;
      pointer_events[index].pressed = pressed;
      pointer_events[index].released = released;
      pointer_events[index].modifiers = modifiers;
      break;
    }
  }
}

void BHVR_Pointer(const sdy_pointer_event_t *evt){
  int index;
  for (index=0; index<MAX_POINTERS; index++) {
    if (index >= last_pointer_event) {
      last_pointer_event++;
      pointer_events[index] = *evt;
      break;
    }
    else if (pointer_events[index].id == evt->id) {
      pointer_events[index] = *evt;
      break;
    }
  }
}

/* Setter functions for pointer and keyboard */
void BHVR_SetKeyboard(SGLint32 id, SGLint32 keycode, SGLbool pressed, SGLbool released, SGLint32 modifiers){
  int index;
    for (index=0; index<MAX_KEYBOARDS; index++) {
      if (index >= last_keyboard_event) {
        last_keyboard_event++;
        keyboard_events[index].id = id;
        keyboard_events[index].keycode = keycode;
        keyboard_events[index].pressed = pressed;
        keyboard_events[index].released = released;
        keyboard_events[index].modifiers = modifiers;
        break;
      }
      else if (keyboard_events[index].id == id) {
        keyboard_events[index].id = id;
        keyboard_events[index].keycode = keycode;
        keyboard_events[index].pressed = pressed;
        keyboard_events[index].released = released;
        keyboard_events[index].modifiers = modifiers;
        break;
      }
    }
  }

void BHVR_Keyboard(const sdy_keyboard_event_t *evt){
  int index;
  for (index=0; index<MAX_KEYBOARDS; index++) {
    if (index >= last_keyboard_event) {
      last_keyboard_event++;
      keyboard_events[index] = *evt;
      break;
    }
    else if (keyboard_events[index].id == evt->id) {
      keyboard_events[index] = *evt;
      break;
    }
  }
}



void BHVR_CursorPosRequest(T_CURSOR_POS_REQUEST_CALLBACK cb, void *data){
  cursor_pos_request_cb = cb;
  cursor_pos_request_data = data;
}

/* Asynchronous ACK function */

void BHVR_SetAsynchronousACK(void){
  BHVR_AsynchronousACK = SGL_TRUE;
}

/* Reset function */

void BHVR_Reset(void){
}

/* Step function */

void BHVR_Step(void){
  BHVR_AsynchronousACK = SGL_FALSE;
}
